package com.rc.evcharger.service;

import com.github.pagehelper.util.StringUtil;
import com.rc.evcharger.common.constant.SocketConstant;
import com.rc.evcharger.common.constant.level.UserLevelConstant;
import com.rc.evcharger.common.enums.DataEnum;
import com.rc.evcharger.common.enums.HlhtOrderStatusEnum;
import com.rc.evcharger.common.redis.RedisDao;
import com.rc.evcharger.common.utils.BeanUtil;
import com.rc.evcharger.common.utils.DataUtil;
import com.rc.evcharger.common.utils.DateHelper;
import com.rc.evcharger.component.UidGenerator;
import com.rc.evcharger.mapper.elec.ElecGunMapper;
import com.rc.evcharger.mapper.elec.ElecPileMapper;
import com.rc.evcharger.mapper.enterprise.EnterpriseMemberMapper;
import com.rc.evcharger.mapper.member.MemberAccountMapper;
import com.rc.evcharger.mapper.member.MemberAccountRecordMapper;
import com.rc.evcharger.mapper.member.MemberInfoMapper;
import com.rc.evcharger.mapper.order.OrderDiscountRecordMapper;
import com.rc.evcharger.mapper.order.OrderInfoMapper;
import com.rc.evcharger.mapper.rc.RcMemberFlagMapper;
import com.rc.evcharger.mapper.rc.RcMemberGainSettingRecordMapper;
import com.rc.evcharger.model.discount.TenantDiscountPolicy;
import com.rc.evcharger.model.elec.ElecGun;
import com.rc.evcharger.model.elec.ElecPile;
import com.rc.evcharger.model.elec.ElecStation;
import com.rc.evcharger.model.enterprise.EnterpriseMember;
import com.rc.evcharger.model.market.MarketActivity;
import com.rc.evcharger.model.market.MarketActivityMember;
import com.rc.evcharger.model.member.MemberAccount;
import com.rc.evcharger.model.member.MemberAccountRecord;
import com.rc.evcharger.model.member.MemberInfo;
import com.rc.evcharger.model.order.OrderDiscountRecord;
import com.rc.evcharger.model.order.OrderInfo;
import com.rc.evcharger.model.rc.RcMemberFlag;
import com.rc.evcharger.model.ticket.MemberTicket;
import com.rc.evcharger.redis.RedChargeDataService;
import com.rc.evcharger.redis.RedOccupy;
import com.rc.evcharger.redis.RedOrderService;
import com.rc.evcharger.service.discount.TenantDiscountPolicyService;
import com.rc.evcharger.service.discount.TenantDiscountTimeService;
import com.rc.evcharger.service.elec.ElecStationService;
import com.rc.evcharger.service.enterprise.EnterpriseSubmemberShareService;
import com.rc.evcharger.service.hlht.HlhtTenantOpenPriceService;
import com.rc.evcharger.service.market.MarketActivityMemberService;
import com.rc.evcharger.service.market.MarketActivityService;
import com.rc.evcharger.service.member.MemberInfoService;
import com.rc.evcharger.service.order.OrderDetailService;
import com.rc.evcharger.service.order.OrderInfoService;
import com.rc.evcharger.service.order.OrderSuspendService;
import com.rc.evcharger.service.rc.RcEnterpriseGainGradeRecordService;
import com.rc.evcharger.service.rc.RcMemberGainGradeRecordService;
import com.rc.evcharger.service.rc.RcMemberGainSettingRecordService;
import com.rc.evcharger.service.ticket.MemberTicketService;
import com.rc.evcharger.service.ugs.TenantUgsLevelGrowingService;
import com.rc.evcharger.vo.cost.UserLevelPriceResult;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

/**
 * 订单结算，所有计算在同一事务内完成
 * Created by Sven on 2021/05/16
 */
@Service
//@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
public class OrderCostServiceImpl implements OrderCostService {
    private static Logger logger = LogManager.getLogger(OrderCostServiceImpl.class);

    @Autowired
    private OrderInfoMapper orderInfoMapper;

    @Autowired
    private OrderSuspendService orderSuspendService;

    @Autowired
    private MemberInfoMapper memberInfoMapper;

    @Autowired
    private ElecGunMapper elecGunMapper;

    @Autowired
    private ElecPileMapper elecPileMapper;

    @Autowired
    private OrderInfoService orderInfoService;

    @Autowired
    private OrderDetailService orderDetailService;

    @Autowired
    private RedChargeDataService redChargeDataService;

    @Autowired
    private RcEnterpriseGainGradeRecordService rcEnterpriseGainGradeRecordService;

    @Autowired
    private OrderDiscountRecordMapper orderDiscountRecordMapper;

    @Autowired
    private RedOrderService redOrderService;

    @Autowired
    private MemberAccountRecordMapper memberAccountRecordMapper;

    @Autowired
    private TenantDiscountPolicyService tenantDiscountPolicyService;

    @Autowired
    private TenantDiscountTimeService tenantDiscountTimeService;

    @Autowired
    private EnterpriseMemberMapper enterpriseMemberMapper;

    @Autowired
    private MemberAccountMapper memberAccountMapper;

    @Autowired
    private RcMemberFlagMapper rcMemberFlagMapper;

    @Autowired
    private MemberTicketService memberTicketService;

    @Autowired
    private MarketActivityService marketActivityService;

    @Autowired
    private MarketActivityMemberService marketActivityMemberService;

    @Autowired
    private RcMemberGainSettingRecordService rcMemberGainSettingRecordService;

    @Autowired
    private MemberInfoService memberInfoService;

    @Autowired
    private ElecStationService elecStationService;

    @Autowired
    private UidGenerator uidGenerator;

    @Autowired
    private HlhtTenantOpenPriceService hlhtTenantOpenPriceService;

    @Autowired
    private RedisDao redisDao;

    /**
     * 结算订单
     *
     * @param orderNum
     * @param stopReason
     */
    @Override
    public synchronized void updateOrderCost(String orderNum, Integer stopReason) {

        //根据内部订单号查找订单信息
        OrderInfo oooorderInfo = orderInfoService.selectByOrderNum(orderNum);

        if ("245".contains(oooorderInfo.getStatus())) {
            logger.error("订单状态245不能进行结算,对应订单号:{},状态:{}", oooorderInfo.getOrderNum(), oooorderInfo.getStatus());
            return;
        }

        //会员信息
        MemberInfo memberInfo = memberInfoMapper.selectByPrimaryKey(oooorderInfo.getMemberId());
        //枪
        ElecGun elecGun = elecGunMapper.selectByPrimaryKey(oooorderInfo.getElecGunId());
        //桩
        ElecPile elecPile = elecPileMapper.selectByPrimaryKey(elecGun.getElecPileId());

        try {
            BigDecimal power = BigDecimal.ZERO;
            BigDecimal baseAmount = BigDecimal.ZERO;
            BigDecimal chargeAmount = BigDecimal.ZERO;
            BigDecimal serviceAmount = BigDecimal.ZERO;
            BigDecimal soc = BigDecimal.ZERO;
            String lastA5Date = "";
            String stopMode = "";
            String pileStopMode = "";
            //采用
            Date endTime = null;
            //读取Redids中的缓存信息

            //待结算状态
            if ("6".contains(oooorderInfo.getStatus())) {

                power = oooorderInfo.getTotalPower();
                baseAmount = oooorderInfo.getTotalElecMoney();
                chargeAmount = oooorderInfo.getTotalMoney();
                serviceAmount = oooorderInfo.getTotalSeviceMoney();
                soc = oooorderInfo.getSoc();
                lastA5Date = DateHelper.dataToString(oooorderInfo.getEndTime(), DateHelper.DATE_COMMON_FORMAT);
                endTime = oooorderInfo.getEndTime();

                //充电中
            } else if ("1".equals(oooorderInfo.getStatus())) {
                //第一次结算取redis的数据
                power = redChargeDataService.getPower(elecPile.getPileRtua(), elecGun.getGunNum(), oooorderInfo.getOrderNum());
                baseAmount = redChargeDataService.getBaseAmount(elecPile.getPileRtua(), elecGun.getGunNum(), oooorderInfo.getOrderNum());
//                chargeAmount = redChargeDataService.getAmount(elecPile.getPileRtua(), elecGun.getGunNum(), memberInfo.getMobile());
                serviceAmount = redChargeDataService.getServiceAmount(elecPile.getPileRtua(), elecGun.getGunNum(), oooorderInfo.getOrderNum());
                soc = redChargeDataService.getSoc(elecPile.getPileRtua(), elecGun.getGunNum(), oooorderInfo.getOrderNum());
                lastA5Date = redChargeDataService.getChargeReportTime(elecPile.getPileRtua(), elecGun.getGunNum(), oooorderInfo.getOrderNum());
                stopMode = redChargeDataService.getStopMode(elecPile.getPileRtua(), elecGun.getGunNum(), oooorderInfo.getOrderNum());
                pileStopMode = redChargeDataService.getPileStopMode(elecPile.getPileRtua(), elecGun.getGunNum(), oooorderInfo.getOrderNum());

                //得到四舍五入后的服务费，基本电费，总价格 并赋值到order0中
                baseAmount = baseAmount.setScale(2, BigDecimal.ROUND_HALF_UP);
                serviceAmount = serviceAmount.setScale(2, BigDecimal.ROUND_HALF_UP);
                chargeAmount = baseAmount.add(serviceAmount);

                if (lastA5Date != null) {
                    endTime = DateHelper.stringToDate(lastA5Date, DateHelper.DATE_COMMON_FORMAT);
                } else {
                    endTime = new Date();
                }
                //结算订单后保存最后时段的充电记录
                orderDetailService.saveByCost(oooorderInfo.getOrderId(), oooorderInfo.getElecPileId(), chargeAmount, baseAmount, serviceAmount, soc, power, endTime);

                //判断停止原因
                this.convertStopReason(stopMode, oooorderInfo);
                if (StringUtil.isEmpty(pileStopMode)) {
                    oooorderInfo.setPileStopReason(0);
                } else {
                    Integer intCode = Integer.parseInt(pileStopMode, 16);
                    oooorderInfo.setPileStopReason(intCode);
                }
            }

            logger.warn("后台结算订单id:" + orderNum + ",桩地址：" + elecPile.getPileRtua() + "orderservice实例地址：" + this.toString());

            //优惠、结算(新)
            updateOrderCostByMemberType(oooorderInfo, null, endTime, baseAmount, serviceAmount, soc, power);


            //清理redis充电数据
            //clearRedis(elecPile.getPileRtua(), elecGun.getGunNum(), orderNum, memberInfo.getMemberId());
        } catch (Exception e) {
            logger.error("结算出错:" + orderNum, e);
        } finally {
            memberInfoMapper.updateChargeStatus(SocketConstant.ELEC_NOT + "", memberInfo.getMemberId());
        }
    }


    /**
     * 个人普通用户订单结算:只能使用个人钱包
     */
    private void updateOrderCostPersonal(OrderInfo oooorderInfo, MemberInfo memberInfo, MemberAccount memberAccount) {
        logger.info("个人普通用户【0个人钱包】订单结算,会员ID:{},内部订单号:{},外部订单号:{}", memberInfo.getMemberId(), oooorderInfo.getOrderNum(), oooorderInfo.getOutOrderNum());

        RcMemberFlag rcMemberFlag = rcMemberFlagMapper.selectByPrimaryKey(memberAccount.getMemberId());

        List<OrderDiscountRecord> orderDiscountRecords0 = new ArrayList<>();
        List<MemberTicket> memberTickets0 = new ArrayList<>();
        List<MarketActivity> marketActivities = new ArrayList<>();
        List<MarketActivityMember> marketActivityMembers = new ArrayList<>();


        //0非会员  1会员
        if ("0".equals(rcMemberFlag.getIsMemberLevel())) {
            //进行优惠券折扣
            UserLevelPriceResult userLevelPriceResult1 = memberTicketService.updateTicketByOrderInfo(oooorderInfo);
            //添加优惠记录
            if (!CollectionUtils.isEmpty(userLevelPriceResult1.getOrderDiscountRecords())) {
                orderDiscountRecords0.addAll(userLevelPriceResult1.getOrderDiscountRecords());
                memberTickets0.addAll(userLevelPriceResult1.getMemberTickets());
            }
        } else {
            //会员权益折扣：生日礼遇，充值消费折扣, 权益金
            UserLevelPriceResult userLevelPriceResult1 = rcMemberGainSettingRecordService.updateOrderInfo(oooorderInfo);

            //添加优惠记录
            if (!CollectionUtils.isEmpty(userLevelPriceResult1.getOrderDiscountRecords())) {
                orderDiscountRecords0.addAll(userLevelPriceResult1.getOrderDiscountRecords());
            }

            //进行优惠券折扣
            UserLevelPriceResult userLevelPriceResult2 = memberTicketService.updateTicketByOrderInfo(oooorderInfo);
            //添加优惠记录
            if (!CollectionUtils.isEmpty(userLevelPriceResult2.getMemberTickets())) {
                memberTickets0.addAll(userLevelPriceResult2.getMemberTickets());
                orderDiscountRecords0.addAll(userLevelPriceResult2.getOrderDiscountRecords());
            }
        }

        //活动满减 后台设置参与用户与站点
        UserLevelPriceResult userLevelPriceResult = marketActivityService.updateMarketActivityByOrderInfo(oooorderInfo);
        if (!CollectionUtils.isEmpty(userLevelPriceResult.getOrderDiscountRecords())) {
            orderDiscountRecords0.addAll(userLevelPriceResult.getOrderDiscountRecords());
            marketActivities.addAll(userLevelPriceResult.getMarketActivities());
            marketActivityMembers.addAll(userLevelPriceResult.getMarketActivityMembers());
        }

        //余额不足情况
        if (memberAccount.getAccount().compareTo(oooorderInfo.getPayAmount()) < 0) {

            oooorderInfo.setStatus("6");

            logger.info("余额不足，进入挂单状态6,个人普通用户订单【0个人钱包】结算成功,订单号={}, chargamout={}, basemount={}, servermount={},payAmount={},discountAmount={},power:{}," +
                            "account={},enterpriseAccount={}"
                    , oooorderInfo.getOrderNum(), oooorderInfo.getTotalMoney(), oooorderInfo.getTotalElecMoney(), oooorderInfo.getTotalSeviceMoney()
                    , oooorderInfo.getPayAmount(), oooorderInfo.getDiscountServiceAmount(), oooorderInfo.getTotalPower(), memberAccount.getAccount(),
                    memberAccount.getEnterpriseAccount());
            return;
        }

        //更新订单状态
        if ("5".equals(oooorderInfo.getStatus()) || "6".equals(oooorderInfo.getStatus())) {
            oooorderInfo.setStatus("4");
        } else if ("1".equals(oooorderInfo.getStatus())) {
            oooorderInfo.setStatus("2");
            oooorderInfo.setOccupyPayTime(oooorderInfo.getEndTime());
        }

        //个人普通用户订单结算:只能使用个人钱包
        memberAccount.setAccount(memberAccount.getAccount().subtract(oooorderInfo.getPayAmount()));
        memberAccount.setGiveAccount(memberAccount.getGiveAccount().subtract(oooorderInfo.getGiveAmount()));
        memberAccount.setOrderCount(memberAccount.getOrderCount() + 1);
        memberAccount.setSaveAmount(memberAccount.getSaveAmount().add(oooorderInfo.getDiscountAmount()));
        //更新消费总金额
        memberAccount.setAllOrderAmount(memberAccount.getAllOrderAmount().add(oooorderInfo.getPayAmount()));

        BigDecimal account = memberAccount.getAccount();
        //解冻赠送金额
        rcMemberGainSettingRecordService.updateGiveAccount(oooorderInfo, memberAccount);
        //更新余额
        memberAccountMapper.updateMemberAccountByMemberId(memberAccount);

        //保存折扣
        if (!CollectionUtils.isEmpty(orderDiscountRecords0)) {
            orderDiscountRecords0.stream().forEach(orderDiscountRecord -> {
                        orderDiscountRecordMapper.insertSelective(orderDiscountRecord);
                    }
            );
        }

        //保存优惠券
        if (!CollectionUtils.isEmpty(memberTickets0)) {
            memberTickets0.stream().forEach(memberTicket -> {
                        memberTicketService.updateByPrimaryKeySelective(memberTicket);
                    }
            );
        }

        //更新最大次数
        if (!CollectionUtils.isEmpty(marketActivities)) {
            marketActivities.stream().forEach(marketActivity -> {
                        marketActivityService.updateByPrimaryKeySelective(marketActivity);
                    }
            );
        }

        //更新用户参与活动次数
        if (!CollectionUtils.isEmpty(marketActivityMembers)) {
            marketActivityMembers.stream().forEach(marketActivityMember -> {
                        marketActivityMemberService.updateByPrimaryKeySelective(marketActivityMember);
                    }
            );
        }

        //参与满返活动
        marketActivityService.insertTicketTypeByMarketActivity(oooorderInfo);

        //增加余额变动记录
        MemberAccountRecord newMemberAccountRecord = new MemberAccountRecord(oooorderInfo, account);
        newMemberAccountRecord.setInTradeNo(uidGenerator.genDiscountOrderNum("S"));
        memberAccountRecordMapper.insertSelective(newMemberAccountRecord);


        logger.info("个人普通用户订单【0个人钱包】结算成功,订单号={}, chargamout={}, basemount={}, servermount={},payAmount={},discountAmount={},power:{}," +
                        "account={},enterpriseAccount={}"
                , oooorderInfo.getOrderNum(), oooorderInfo.getTotalMoney(), oooorderInfo.getTotalElecMoney(), oooorderInfo.getTotalSeviceMoney()
                , oooorderInfo.getPayAmount(), oooorderInfo.getDiscountAmount(), oooorderInfo.getTotalPower(), memberAccount.getAccount(),
                memberAccount.getEnterpriseAccount());
    }

    /**
     * 按会员类型结算订单
     */
    private void updateOrderCostByMemberType(OrderInfo oooorderInfo, Date startTime, Date endTime, BigDecimal baseAmount, BigDecimal serviceAmount,
                                             BigDecimal soc, BigDecimal power) throws Exception {
        //复制订单对帐以保存中间结算结果
        OrderInfo tmpOrder = new OrderInfo();
        tmpOrder.setEndTime(endTime);
        tmpOrder.setStartTime(startTime);
        tmpOrder.setTotalPower(power);
//        tmpOrder.setStatus(SocketConstant.ORDER_STATUS_USED);
        tmpOrder.setSoc(soc);
        tmpOrder.setHlhtOrderStatus(HlhtOrderStatusEnum.HlhtOrderStatus4.getCode());

        //将order复制到order0
        BeanUtil.setBeanByOtherBeanWithoutNull(oooorderInfo, tmpOrder);

        BigDecimal chargeAmount = baseAmount.add(serviceAmount);
        BigDecimal payAmount = chargeAmount;

        //赋值到订单表中;
        oooorderInfo.setTotalSeviceMoney(serviceAmount);
        oooorderInfo.setTotalElecMoney(baseAmount);
        oooorderInfo.setTotalMoney(chargeAmount);
        oooorderInfo.setPayAmount(payAmount);
        oooorderInfo.setDiscountAmount(BigDecimal.ZERO); //优惠金额设为0
        oooorderInfo.setTotalPower(power);

        //占位费也进行赋值
        oooorderInfo.setTotalMoney(oooorderInfo.getTotalMoney().add(oooorderInfo.getOccupyAmount()));
        oooorderInfo.setPayAmount(oooorderInfo.getPayAmount().add(oooorderInfo.getOccupyAmount()));

        //获取会员信息
        MemberInfo memberInfo = memberInfoMapper.selectByPrimaryKey(oooorderInfo.getMemberId());
        //获取会员账户
        MemberAccount memberAccount = memberAccountMapper.selectByMemberIdForceMaster(memberInfo.getMemberId());


        //新增占位费功能
        int i = elecStationService.selectOccupyStatusByelecStationId(oooorderInfo.getElecStationId());
        if (i == 1 && !"6".equals(oooorderInfo.getStatus())) {
            //如果是充电中结算则新增占位key
            if ("1".equals(oooorderInfo.getStatus())) {
                //新增占位费功能
                String value = DateHelper.dataToString(oooorderInfo.getEndTime(), DateHelper.DATE_COMMON_FORMAT);
                ElecPile elecPile = elecPileMapper.selectByPrimaryKey(oooorderInfo.getElecPileId());
                ElecGun elecGun = elecGunMapper.selectByPrimaryKey(oooorderInfo.getElecGunId());
                String occupyKey = DataUtil.getCurrDataKey(elecGun.getPileRuta(), elecGun.getGunNum(), DataEnum.OCCUPY_INFO.getCode(), oooorderInfo.getOrderNum());
                //插入占位费
                redisDao.putHashSession(RedOccupy.OCCUPY, occupyKey, value);

//                orderInfoService.updateStatusByOrderInfo(orderInfo.getOrderId());
            }

            //存在占位费不进行结算
            oooorderInfo.setStatus("5"); //占位中
            logger.info("订单占位费，只更新订单，不进行余额结算,对应订单号:{}", oooorderInfo.getOrderNum());
        } else {
            //todo 不存在占位费则进行结算
            //按会员类型结算,oooorderInfo可能会改变
            //member_type 会员类型(0个人 1企业主帐户 2企业子帐户 3互联互通用户) 默认0
            if (SocketConstant.STR_CON0.equals(oooorderInfo.getAccountType())) { //个人钱包
                updateOrderCostPersonal(oooorderInfo, memberInfo, memberAccount);
            } else if (SocketConstant.STR_CON1.equals(oooorderInfo.getAccountType())) {
                updateOrderCostEnterprise(oooorderInfo, memberInfo, memberAccount);
            }if (SocketConstant.STR_CON3.equals(oooorderInfo.getAccountType())) {
                updateOrderCostRefund(oooorderInfo, memberInfo, memberAccount);
            }
        }


        //订单结算(oooorderInfo可能会改变)
        orderInfoMapper.updateByPrimaryKeySelective(oooorderInfo);

        //更新会员状态
        memberInfoService.updateMemberInfoStatus(memberInfo.getMemberId());
        //会员等级增加成长值&升级
//        tenantUgsLevelGrowingService.updateByTotalPower(memberInfo.getMemberId(), oooorderInfo);
    }


    /**
     * 企业帐号（主帐号+子帐号）：可以使用0个人钱包/1企业钱包/2共享余额
     *
     * @param oooorderInfo
     * @param memberInfo
     * @param memberAccount
     */
    private void updateOrderCostEnterprise(OrderInfo oooorderInfo, MemberInfo memberInfo, MemberAccount memberAccount) {
        logger.info("企业帐号（主帐号+子帐号）订单结算,会员ID:{},内部订单号:{},外部订单号:{}", memberInfo.getMemberId(), oooorderInfo.getOrderNum(), oooorderInfo.getOutOrderNum());

        RcMemberFlag rcMemberFlag = rcMemberFlagMapper.selectByPrimaryKey(memberInfo.getMemberId());
        EnterpriseMember enterpriseMember = enterpriseMemberMapper.selectByPrimaryKey(rcMemberFlag.getEnterpriseId());

        List<OrderDiscountRecord> orderDiscountRecords0 = new ArrayList<>();
        List<MemberTicket> memberTickets0 = new ArrayList<>();
        List<MarketActivity> marketActivities = new ArrayList<>();


        //企业权益折扣
        UserLevelPriceResult userLevelPriceResult = rcEnterpriseGainGradeRecordService.updateOrderInfo(oooorderInfo, enterpriseMember.getEnterpriseId(), enterpriseMember.getAllRechargeEnterpriseAccount());
        if (!CollectionUtils.isEmpty(userLevelPriceResult.getOrderDiscountRecords())) {
            orderDiscountRecords0.addAll(userLevelPriceResult.getOrderDiscountRecords());
        }

        //优惠券折扣减免
        UserLevelPriceResult userLevelPriceResult1 = memberTicketService.updateTicketByOrderInfo(oooorderInfo);
        if (!CollectionUtils.isEmpty(userLevelPriceResult1.getMemberTickets())) {
            memberTickets0.addAll(userLevelPriceResult1.getMemberTickets());
            orderDiscountRecords0.addAll(userLevelPriceResult1.getOrderDiscountRecords());
        }

        //活动满减 后台设置参与用户与站点
        UserLevelPriceResult userLevelPriceResult2 = marketActivityService.updateMarketActivityByOrderInfo(oooorderInfo);
        if (!CollectionUtils.isEmpty(userLevelPriceResult2.getOrderDiscountRecords())) {
            orderDiscountRecords0.addAll(userLevelPriceResult2.getOrderDiscountRecords());
            marketActivities.addAll(userLevelPriceResult2.getMarketActivities());
        }

        BigDecimal allAmount = enterpriseMember.getEnterpriseAccount().add(enterpriseMember.getRemainCreditAmount());

        //余额充足时企业余额扣减，否则企业额度扣减
        BigDecimal resultAmount = enterpriseMember.getEnterpriseAccount().subtract(oooorderInfo.getPayAmount());
        if (resultAmount.compareTo(BigDecimal.ZERO) >= 0) {
            enterpriseMember.setEnterpriseAccount(resultAmount);
        } else if (allAmount.compareTo(oooorderInfo.getPayAmount()) >= 0) {
            BigDecimal result = oooorderInfo.getPayAmount().subtract(enterpriseMember.getEnterpriseAccount());

            enterpriseMember.setEnterpriseAccount(BigDecimal.ZERO);
            enterpriseMember.setRemainCreditAmount(enterpriseMember.getRemainCreditAmount().subtract(result));
        } else {
            oooorderInfo.setStatus("6"); //待结算状态
            logger.info("企业余额不足，进入挂单状态6,个人普通用户订单【0个人钱包】结算成功,订单号={}, chargamout={}, basemount={}, servermount={},payAmount={},discountAmount={},power:{}," +
                            "account={},enterpriseAccount={}"
                    , oooorderInfo.getOrderNum(), oooorderInfo.getTotalMoney(), oooorderInfo.getTotalElecMoney(), oooorderInfo.getTotalSeviceMoney()
                    , oooorderInfo.getPayAmount(), oooorderInfo.getDiscountServiceAmount(), oooorderInfo.getTotalPower(), memberAccount.getAccount(),
                    enterpriseMember.getEnterpriseAccount());
            return;
        }

        //更新订单状态
        if ("5".equals(oooorderInfo.getStatus()) || "6".equals(oooorderInfo.getStatus())) {
            oooorderInfo.setStatus("4");
        } else if ("1".equals(oooorderInfo.getStatus())) {
            oooorderInfo.setStatus("2");
            oooorderInfo.setOccupyPayTime(oooorderInfo.getEndTime());
        }

        //结算订单后保存最后时段的充电记录
        orderDetailService.saveByCost(oooorderInfo.getOrderId(), oooorderInfo.getElecPileId(), oooorderInfo.getTotalSeviceMoney().add(oooorderInfo.getTotalElecMoney()), oooorderInfo.getTotalElecMoney(), oooorderInfo.getTotalSeviceMoney(), oooorderInfo.getSoc(), oooorderInfo.getTotalPower(), oooorderInfo.getEndTime());


        enterpriseMemberMapper.updateByPrimaryKeySelective(enterpriseMember);  //企业余额更新

        //保存折扣
        if (!CollectionUtils.isEmpty(orderDiscountRecords0)) {
            orderDiscountRecords0.stream().forEach(orderDiscountRecord -> {
                        orderDiscountRecordMapper.insertSelective(orderDiscountRecord);
                    }
            );
        }

        //保存优惠券
        if (!CollectionUtils.isEmpty(memberTickets0)) {
            memberTickets0.stream().forEach(memberTicket -> {
                        memberTicketService.updateByPrimaryKeySelective(memberTicket);
                    }
            );
        }

        //更新最大次数
        if (!CollectionUtils.isEmpty(marketActivities)) {
            marketActivities.stream().forEach(marketActivity -> {
                        marketActivityService.updateByPrimaryKeySelective(marketActivity);
                    }
            );
        }

        //参与满返活动
        marketActivityService.insertTicketTypeByMarketActivity(oooorderInfo);

        //增加余额变动记录
        MemberAccountRecord record = new MemberAccountRecord(oooorderInfo, memberAccount.getEnterpriseAccount());
        record.setMemberId(oooorderInfo.getMemberId());
        record.setTenantCode(oooorderInfo.getTenantCode());
        record.setLocalTradeNo(oooorderInfo.getOrderNum());
        record.setRecordType("1");
        record.setEnterpeiseId(enterpriseMember.getEnterpriseId());
        record.setAmount(oooorderInfo.getPayAmount());
        record.setResult(enterpriseMember.getEnterpriseAccount().add(enterpriseMember.getRemainCreditAmount()));
        record.setCreatedTime(new Date());
        record.setInTradeNo(uidGenerator.genDiscountOrderNum("S"));
        record.setAccountType(oooorderInfo.getAccountType());
        record.setRemark("充电扣费");
        memberAccountRecordMapper.insertSelective(record);

        logger.info("企业帐号（主帐号+子帐号）订单结算成功,订单号={}, chargamout={}, basemount={}, servermount={},payAmount={},discountAmount={},power:{}"
                , oooorderInfo.getOrderNum(), oooorderInfo.getTotalMoney(), oooorderInfo.getTotalElecMoney(), oooorderInfo.getTotalSeviceMoney()
                , oooorderInfo.getPayAmount(), oooorderInfo.getDiscountServiceAmount(), oooorderInfo.getTotalPower());

    }




    /**
     * 先付后退钱包扣款
     *
     * @param oooorderInfo
     * @param memberInfo
     * @param memberAccount
     */
    private void updateOrderCostRefund(OrderInfo oooorderInfo, MemberInfo memberInfo, MemberAccount memberAccount) {
        logger.info("先付后退订单结算,会员ID:{},内部订单号:{},外部订单号:{}", memberInfo.getMemberId(), oooorderInfo.getOrderNum(), oooorderInfo.getOutOrderNum());

        RcMemberFlag rcMemberFlag = rcMemberFlagMapper.selectByPrimaryKey(memberInfo.getMemberId());
        EnterpriseMember enterpriseMember = enterpriseMemberMapper.selectByPrimaryKey(rcMemberFlag.getEnterpriseId());

        List<OrderDiscountRecord> orderDiscountRecords0 = new ArrayList<>();
        List<MemberTicket> memberTickets0 = new ArrayList<>();
        List<MarketActivity> marketActivities = new ArrayList<>();


        //优惠券折扣减免
        UserLevelPriceResult userLevelPriceResult1 = memberTicketService.updateTicketByOrderInfo(oooorderInfo);
        if (!CollectionUtils.isEmpty(userLevelPriceResult1.getMemberTickets())) {
            memberTickets0.addAll(userLevelPriceResult1.getMemberTickets());
            orderDiscountRecords0.addAll(userLevelPriceResult1.getOrderDiscountRecords());
        }

        //变更预付金额与退款金额
        oooorderInfo.setPreAmount(memberAccount.getPaymentRefundAccount());
        oooorderInfo.setRefundAmount(memberAccount.getPaymentRefundAccount().subtract(oooorderInfo.getPayAmount()));

        //余额不足情况
        if (memberAccount.getPaymentRefundAccount().compareTo(oooorderInfo.getPayAmount()) < 0) {

            oooorderInfo.setStatus("6");

            logger.info("先付后退余额不足，进入挂单状态6,个人普通用户订单【0个人钱包】结算成功,订单号={}, chargamout={}, basemount={}, servermount={},payAmount={},discountAmount={},power:{}," +
                            "account={},enterpriseAccount={}"
                    , oooorderInfo.getOrderNum(), oooorderInfo.getTotalMoney(), oooorderInfo.getTotalElecMoney(), oooorderInfo.getTotalSeviceMoney()
                    , oooorderInfo.getPayAmount(), oooorderInfo.getDiscountServiceAmount(), oooorderInfo.getTotalPower(), memberAccount.getAccount(),
                    memberAccount.getPaymentRefundAccount());
            return;
        }

        //更新订单状态
        if ("5".equals(oooorderInfo.getStatus()) || "6".equals(oooorderInfo.getStatus())) {
            oooorderInfo.setStatus("4");
        } else if ("1".equals(oooorderInfo.getStatus())) {
            oooorderInfo.setStatus("2");
            oooorderInfo.setOccupyPayTime(oooorderInfo.getEndTime());
        }

        //个人普通用户订单结算:只能使用个人钱包
        memberAccount.setPaymentRefundAccount(memberAccount.getPaymentRefundAccount().subtract(oooorderInfo.getPayAmount()));
        memberAccount.setOrderCount(memberAccount.getOrderCount() + 1);
        memberAccount.setSaveAmount(memberAccount.getSaveAmount().add(oooorderInfo.getDiscountAmount()));
        //更新消费总金额
        memberAccount.setAllOrderAmount(memberAccount.getAllOrderAmount().add(oooorderInfo.getPayAmount()));
        //退款金额
        oooorderInfo.setRefundAmount(memberAccount.getPaymentRefundAccount());

        //解冻赠送金额
        rcMemberGainSettingRecordService.updateGiveAccount(oooorderInfo, memberAccount);
        //更新余额
        memberAccountMapper.updateMemberAccountByMemberId(memberAccount);

        //结算订单后保存最后时段的充电记录
        orderDetailService.saveByCost(oooorderInfo.getOrderId(), oooorderInfo.getElecPileId(), oooorderInfo.getTotalSeviceMoney().add(oooorderInfo.getTotalElecMoney()), oooorderInfo.getTotalElecMoney(), oooorderInfo.getTotalSeviceMoney(), oooorderInfo.getSoc(), oooorderInfo.getTotalPower(), oooorderInfo.getEndTime());
        //保存折扣
        if (!CollectionUtils.isEmpty(orderDiscountRecords0)) {
            orderDiscountRecords0.stream().forEach(orderDiscountRecord -> {
                        orderDiscountRecordMapper.insertSelective(orderDiscountRecord);
                    }
            );
        }

        //保存优惠券
        if (!CollectionUtils.isEmpty(memberTickets0)) {
            memberTickets0.stream().forEach(memberTicket -> {
                        memberTicketService.updateByPrimaryKeySelective(memberTicket);
                    }
            );
        }

        //更新最大次数
        if (!CollectionUtils.isEmpty(marketActivities)) {
            marketActivities.stream().forEach(marketActivity -> {
                        marketActivityService.updateByPrimaryKeySelective(marketActivity);
                    }
            );
        }

        //参与满返活动
        marketActivityService.insertTicketTypeByMarketActivity(oooorderInfo);

        //增加余额变动记录
        MemberAccountRecord record = new MemberAccountRecord(oooorderInfo, memberAccount.getEnterpriseAccount());
        record.setMemberId(oooorderInfo.getMemberId());
        record.setTenantCode(oooorderInfo.getTenantCode());
        record.setLocalTradeNo(oooorderInfo.getOrderNum());
        record.setRecordType("1");
        record.setEnterpeiseId(enterpriseMember.getEnterpriseId());
        record.setAmount(oooorderInfo.getPayAmount());
        record.setResult(enterpriseMember.getEnterpriseAccount().add(enterpriseMember.getRemainCreditAmount()));
        record.setCreatedTime(new Date());
        record.setInTradeNo(uidGenerator.genDiscountOrderNum("S"));
        record.setAccountType(oooorderInfo.getAccountType());
        record.setRemark("充电扣费");
        memberAccountRecordMapper.insertSelective(record);

        logger.info("企业帐号（主帐号+子帐号）订单结算成功,订单号={}, chargamout={}, basemount={}, servermount={},payAmount={},discountAmount={},power:{}"
                , oooorderInfo.getOrderNum(), oooorderInfo.getTotalMoney(), oooorderInfo.getTotalElecMoney(), oooorderInfo.getTotalSeviceMoney()
                , oooorderInfo.getPayAmount(), oooorderInfo.getDiscountServiceAmount(), oooorderInfo.getTotalPower());

    }


    /**
     * 停止方式：0：手动停止  1：故障停止  2：充满停止 3：余额不足停止 4:紧急按钮停止;
     */
    private void convertStopReason(String stopMode, OrderInfo order) {
        //判断是否是余额不足停止;
        if (stopMode == null) {
            //电桩主动停止
            order.setStopReason(SocketConstant.STOP_BMS_0X2);

            if (order.getSoc().intValue() >= 99) {
                order.setStopReason(SocketConstant.STOP_ELEC_FULL_0x9);
            }
//            return;
        } else {
            order.setStopReason(Integer.valueOf(stopMode));
        }

    }

    // 清空redis中对应的数据
    @Override
    public void clearRedis(String rtua, String gunNum, String orderNum, Long memberId) {
        if (gunNum.length() < 2) {
            gunNum = "0" + gunNum;
        }

        MemberInfo memberInfo = memberInfoMapper.selectByPrimaryKey(memberId);

        redOrderService.removeOrder(rtua, gunNum, orderNum);
        redOrderService.removeOrder(rtua, gunNum, memberInfo.getMobile());
        //redMemberService.removeMember(rtua, gunNum, memberId);
        //redisService.deleteCurrentData(rtua, gunNum, orderNum);

        //批量删除充电数据
        redChargeDataService.clearAllDate(rtua, gunNum, orderNum);
        //批量删除充电数据 旧
        redChargeDataService.clearAllDate(rtua, gunNum, memberInfo.getMobile());

    }

    @Override
    public String updateOccupyOrderinfoCost(Long elecPileId, Long gunId) {
        ElecPile elecPile = elecPileMapper.selectByPrimaryKey(elecPileId);
        ElecStation elecStation = elecStationService.selectByPrimaryKey(elecPile.getElecStationId());
        ElecGun elecGun = elecGunMapper.selectByPrimaryKey(gunId);
        OrderInfo orderInfo = orderInfoMapper.selecOccupytByPileIdAndGunId(elecPileId, gunId);

        if (orderInfo == null || "4".equals(orderInfo.getStatus()) || "2".equals(orderInfo.getStatus())) {
            logger.error("占位费订单的订单为空，对应站点：{},对应桩：{}，对应枪号:{}", elecStation.getStationName(), elecPile.getPileNo(), elecGun.getGunNum());
            return null;
        }

        String occupyKey = DataUtil.getCurrDataKey(elecGun.getPileRuta(), elecGun.getGunNum(), DataEnum.OCCUPY_INFO.getCode(), orderInfo.getOrderNum());
        //插入占位费
        Object hashSession = redisDao.getHashSession(RedOccupy.OCCUPY, occupyKey);
        if (hashSession == null) {
            logger.error("占位费订单的redisKEY为空置，对应订单号:{}", orderInfo.getOrderNum());
            return null;
        }

        //计算占位费
        long min = (new Date().getTime() - orderInfo.getEndTime().getTime()) / 1000 / 60; //分钟
        long result = min - elecStation.getOccupyFree();
        if (result <= 0) {
            //不扣费
            orderInfo.setOccupyAmount(BigDecimal.ZERO);
        } else {
            long hour = result / 60; //小时
            long yu = result % 60;  //取余
            if (yu > 0) {
                hour = hour + 1;//有余数+1
            }

            BigDecimal occupyAmount = elecStation.getOccupyPrice().multiply(new BigDecimal(hour));
            orderInfo.setOccupyAmount(occupyAmount); //占位费
        }

        orderInfo.setOccupyDuration((int) min); //占用时长/分钟
        orderInfo.setOccupyPayTime(new Date());
        orderInfo.setStatus("4"); //订单已完成
        orderInfo.setOccupyPrice("免费" + elecStation.getOccupyFree() + "分钟,单价" + elecStation.getOccupyPrice() + "/小时");
        orderInfo.setTotalMoney(orderInfo.getTotalMoney().add(orderInfo.getOccupyAmount()));
        orderInfo.setPayAmount(orderInfo.getPayAmount().add(orderInfo.getOccupyAmount()));

        MemberInfo memberInfo = memberInfoService.selectByPrimaryKey(orderInfo.getMemberId());
        MemberAccount memberAccount = memberAccountMapper.selectByPrimaryKey(orderInfo.getMemberId());

        //结算扣费
        if (SocketConstant.STR_CON0.equals(orderInfo.getAccountType())) { //个人钱包
            updateOrderCostPersonal(orderInfo, memberInfo, memberAccount);
        } else if (SocketConstant.STR_CON1.equals(orderInfo.getAccountType())) {
            updateOrderCostEnterprise(orderInfo, memberInfo, memberAccount);
        }else if (SocketConstant.STR_CON3.equals(orderInfo.getAccountType())) {
            updateOrderCostRefund(orderInfo, memberInfo, memberAccount);
        }

        orderInfoMapper.updateByPrimaryKeySelective(orderInfo);

        redisDao.delHashKeyMap(RedOccupy.OCCUPY, occupyKey);
        logger.info("占位费订单结算完成,订单号：{}，本次占位时长:{}分钟，免费:{}分钟，单价:{},收费:{}", orderInfo.getOrderNum(), min, elecStation.getOccupyFree(), elecStation.getOccupyPrice(), orderInfo.getOccupyAmount());

        return orderInfo.getOrderNum();
    }

    public static void main(String[] args) {
        Calendar instance = Calendar.getInstance();
        Date time = instance.getTime();
        instance.add(Calendar.MINUTE, -60);
        Date time1 = instance.getTime();
        long min = (time.getTime() - time1.getTime()) / 1000 / 60; //分钟
        System.out.println(min);
    }
}
